home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / VGX / shadows / shadow_scn.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  16KB  |  548 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.     shadow_scn.c - Read a scene description from file, build data structures.
  19.  
  20.     Tim Heidmann, Silicon Graphics
  21.     Created    June 21, 1991
  22.     Last Edit  November 25, 1991
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <gl.h>
  27. #include <gl/image.h>
  28. #include <device.h>
  29. #include <math.h>
  30. #include <string.h>
  31. #include "shadows.h"
  32. #include "glo_obj.h"
  33. #include "vect.h"
  34.  
  35.  
  36. /* Default shadowed and highlit material values */
  37. #define MATEMISOFF 0
  38. #define MATAMBIOFF 4
  39. #define MATDIFFOFF 8
  40. #define MATSPECOFF 12
  41. #define MATSHINOFF 16
  42. float defaultLitMaterial[] = {
  43.     EMISSION, 0.0, 0.0, 0.0,
  44.      AMBIENT, 0.2, 0.2, 0.2,
  45.      DIFFUSE, 0.8, 0.8, 0.8,
  46.     SPECULAR, 0.0, 0.0, 0.0,
  47.    SHININESS, 0.0,
  48.       LMNULL
  49. };
  50. float defaultShadowMaterial[] = {
  51.     EMISSION, 0.0, 0.0, 0.0,
  52.      AMBIENT, 0.2, 0.2, 0.2,
  53.      DIFFUSE, 0.0, 0.0, 0.0,
  54.     SPECULAR, 0.0, 0.0, 0.0,
  55.    SHININESS, 0.0,
  56.       LMNULL
  57. };
  58. float defaultHighMaterial[] = {
  59.     EMISSION, 0.0, 0.0, 0.0,
  60.      AMBIENT, 0.0, 0.0, 0.0,
  61.      DIFFUSE, 0.8, 0.8, 0.8,
  62.     SPECULAR, 0.0, 0.0, 0.0,
  63.    SHININESS, 0.0,
  64.       LMNULL
  65. };
  66. #define MATDEFLEN (sizeof(defaultHighMaterial)/sizeof(float))
  67.  
  68. #define LGTAMBOFF 0
  69. #define LGTCOLOFF 4
  70. #define LGTPOSOFF 8
  71. #define LGTSPDOFF 13
  72. #define LGTSPLOFF 17
  73. float defaultLight[] = {
  74.       AMBIENT, 0.0, 0.0, 0.0,
  75.        LCOLOR, 1.0, 1.0, 1.0,
  76.      POSITION, 0.0, 0.0, 1.0, 0.0,
  77. SPOTDIRECTION, 0.0, 0.0, -1.0,
  78.     SPOTLIGHT, 0.0, 180.0,
  79.        LMNULL
  80. };
  81. #define LGTDEFLEN (sizeof(defaultLight)/sizeof(float))
  82. float defaultLight_posn[] = {0.0, 0.0, 10000.0};
  83.  
  84. float FlatGray[] = {
  85.     EMISSION, 0.0, 0.0, 0.0,
  86.      AMBIENT, 1.0, 1.0, 1.0,
  87.      DIFFUSE, 1.0, 1.0, 1.0,
  88.     SPECULAR, 0.0, 0.0, 0.0,
  89.    SHININESS, 20.0,
  90.       LMNULL
  91. };
  92. float FlatGrayA[] = {
  93.     EMISSION, 0.0, 0.0, 0.0,
  94.      AMBIENT, 1.0, 1.0, 1.0,
  95.      DIFFUSE, 0.0, 0.0, 0.0,
  96.     SPECULAR, 0.0, 0.0, 0.0,
  97.    SHININESS, 20.0,
  98.       LMNULL
  99. };
  100. float FlatGrayH[] = {
  101.     EMISSION, 0.0, 0.0, 0.0,
  102.      AMBIENT, 0.0, 0.0, 0.0,
  103.      DIFFUSE, 1.0, 1.0, 1.0,
  104.     SPECULAR, 0.0, 0.0, 0.0,
  105.    SHININESS, 20.0,
  106.       LMNULL
  107. };
  108.  
  109. float RightRed[] = {
  110.      AMBIENT, 0.0, 0.0, 0.0,
  111.       LCOLOR, 1.0, 0.0, 0.0,
  112.     POSITION, 1.0, 1.0, 1.0, 0.0,
  113.       LMNULL
  114. };
  115. float LeftBlue[] = {
  116.      AMBIENT, 0.0, 0.0, 0.0,
  117.       LCOLOR, 0.0, 0.0, 1.0,
  118.     POSITION, -1.0, 1.0, 1.0, 0.0,
  119.       LMNULL
  120. };
  121. float theLModel[] = {
  122.      AMBIENT, 0.2, 0.2, 0.2,
  123.  LOCALVIEWER, 0.0,
  124.  ATTENUATION, 1.0, 0.0,
  125.      TWOSIDE, 0.0,
  126.       LMNULL
  127. };
  128.  
  129. #define SS_UNDEFINED -1
  130. #define SS_WINDOW 0
  131. #define SS_LOOKAT 1
  132. #define SS_MODEL  2
  133. #define SS_XMODEL 17
  134. #define SS_LIGHT  3
  135. #define SS_POSITI 4
  136. #define SS_ROTATI 5
  137. #define SS_SCALE  6
  138. #define SS_TEXTUR 18
  139. #define SS_MATERI 7
  140. #define SS_SPECUL 8
  141. #define SS_SHININ 9
  142. #define SS_DIFFUS 10
  143. #define SS_EMISSI 11
  144. #define SS_AMBIEN 12
  145. #define SS_LCOLOR 13
  146. #define SS_SPOTDI 14
  147. #define SS_SPOTLI 15
  148. #define SS_JITTER 19
  149. #define SS_END    16
  150.  
  151. struct scmd_tag {
  152.     int index;
  153.     char *name;
  154. } SceneCommands[] = {
  155.     {SS_WINDOW, "WIN"  },    /* WINDOW height near far                      */
  156.     {SS_LOOKAT, "LOO"  },    /* LOOKAT eyex eyey eyez gazex gazey gazez     */
  157.     {SS_MODEL , "MOD"  },    /* MODEL filename   (shadow-casting model)     */
  158.     {SS_XMODEL, "XMO"  },    /* XMODEL filename  (non shadow-casting model) */
  159.     {SS_LIGHT , "LIG"  },    /* LIGHT <light properties...> END             */
  160.                  /*   Light properties are AMBIENT, LCOLOR,     */
  161.                  /*   POSITION, SPOTDIRECTION, and SPOTLIGHT.   */
  162.     {SS_POSITI, "POS"  },    /* POSITION x y z   (for models)               */
  163.                  /* POSITION x y z w (for lights)               */
  164.     {SS_ROTATI, "ROT"  },    /* ROTATION xrot yrot zrot                     */
  165.     {SS_SCALE , "SCA"  },    /* SCALE s                                     */
  166.     {SS_TEXTUR, "TEX"  },    /* TEXTURE filename                            */
  167.     {SS_MATERI, "MAT"  },    /* MATERIAL <material properties...> END       */
  168.                  /*   Material properties are EMISSION, AMBIENT,*/
  169.                  /*   DIFFUSE, SPECULAR, and SHININESS.         */
  170.     {SS_SPECUL, "SPE"  },    /* SPECULAR r g b   (color components,0.0-1.0) */
  171.     {SS_SHININ, "SHI"  },    /* SHININESS s      (Specular exp, 0.0-128.0)  */
  172.     {SS_DIFFUS, "DIF"  },    /* DIFFUSE r g b                               */
  173.     {SS_EMISSI, "EMI"  },    /* EMISSION r g b                              */
  174.     {SS_AMBIEN, "AMB"  },    /* AMBIENT r g b                               */
  175.     {SS_LCOLOR, "LCO"  },    /* LCOLOR r g b                                */
  176.     {SS_LCOLOR, "COL"  },    /* COLOR r g b                                 */
  177.     {SS_SPOTDI, "SPOTD"},    /* SPOTDIRECTION dx dy dz                      */
  178.     {SS_SPOTLI, "SPOTL"},    /* SPOTLIGHT exp spread                        */
  179.                  /*   (exponent 0.0-128.0, spread: 0.0-90.0)    */
  180.     {SS_JITTER, "JIT"  },    /* JITTER xrange yrange zrange                 */
  181.     {SS_END   , "END"  }     /* END              (for material or light def)*/
  182. };
  183. #define NSCENECMDS (sizeof(SceneCommands)/sizeof(struct scmd_tag))
  184.  
  185. PolyDataRec NullPolyData = {0, 0, NULL, NULL};
  186.  
  187. /* Forward declarations */
  188. void
  189. AddEdge(EdgePtr edgeList, int *nEdgesp, int v1, int v2, int thisFace,
  190.     int *iEdgep, int *iSidep);
  191. PolyDataPtr
  192. GetPolyData(glo_ObjPtr pdl);
  193.  
  194.  
  195. InitScene() {
  196.     int i, done, localDone, count, theCommand;
  197.     int iTmp, iList[30], iMaterial, iTexture;
  198.     float fTmp[30], fLit[30], fHigh[30], fShad[30], x;
  199.     long *itex, xtex, ytex;
  200.     char cmd[60], objFileName[60];
  201.     FILE *inf;
  202.  
  203.     /* Set flags and constant values */
  204.     vmatcopy(IdentMat, scene_rotMatrix);
  205.     iMaterial = 1;
  206.     iTexture = 1;
  207.  
  208.     /* Read and parse the scene file, if specified */
  209.     if (sceneFileName != NULL) {
  210.     if ((inf = fopen(sceneFileName, "r")) == NULL) {
  211.         fprintf(stderr, "Cannot open scene file %s\n", sceneFileName);
  212.         exit(1);
  213.     }
  214.     fscanf(inf, "%s", cmd);
  215.     if (strcmp(cmd, "ShadowScene") != 0) {
  216.         fprintf(stderr, "File %s is not a Shadow Scene file.\n",
  217.         sceneFileName);
  218.         exit(1);
  219.     }
  220.  
  221.     for (done = FALSE; !done; ) {
  222.         count = fscanf(inf, "%s", cmd);
  223.         if (count == EOF) {
  224.         done = TRUE;
  225.         continue;
  226.         }
  227.         switch (theCommand = FindCommand(cmd)) {
  228.         /* Camera, and view parameters */
  229.         case SS_WINDOW:
  230.         count = fscanf(inf, "%f %f %f", viewWindow, viewWindow+1,
  231.             viewWindow+2);
  232.         break;
  233.         case SS_LOOKAT:
  234.         count = fscanf(inf, "%f %f %f %f %f %f", eyex, eyex+1, eyex+2,
  235.             gazex, gazex+1, gazex+2);
  236.         break;
  237.  
  238.         /* Model geometry and scene, model, light positioning */
  239.         case  SS_MODEL:
  240.         case  SS_XMODEL:
  241.         fscanf(inf, "%s", objFileName);
  242.         if ((obj_drawlist[nObjects]=glo_ReadObj(objFileName)) != NULL) {
  243.             /* We've got a glo_Object file.  Get edge adjacency data. */
  244.             obj_data[nObjects] = (theCommand == SS_MODEL) ?
  245.             GetPolyData(obj_drawlist[nObjects]) :
  246.             &NullPolyData;
  247.         } else if (ReadPDataObj(objFileName,
  248.             obj_drawlist+nObjects, obj_data+nObjects)) {
  249.             /* Got a binary geometry & data file */
  250.             if (theCommand == SS_XMODEL) {
  251.             /* Remove any edge data for non-shadowing objects */
  252.             free(obj_data[nObjects]->faces);
  253.             obj_data[nObjects]->faces = NULL;
  254.             free(obj_data[nObjects]->edges);
  255.             obj_data[nObjects]->edges = NULL;
  256.             obj_data[nObjects]->nFaces = 0;
  257.             obj_data[nObjects]->nEdges = 0;
  258.             }
  259.         } else {
  260.             /* Cannot recognize this file */
  261.             fprintf(stderr, "Cannot open object file %s\n",
  262.             objFileName);
  263.             exit(1);
  264.         }
  265.  
  266.         /* Initialize various parameters */
  267.         for (i=0; i<3; i++) obj_posn[nObjects][i] = 0.0;
  268.         obj_scale[nObjects] = 1.0;
  269.         vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
  270.         obj_litMaterial[nObjects] = -1;
  271.         obj_texture[nObjects] = 0;
  272.  
  273.         nObjects++;
  274.         break;
  275.  
  276.         case SS_POSITI:
  277.         fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
  278.         if (nObjects > 0)
  279.             for (i=0; i<3; i++)
  280.             obj_posn[nObjects-1][i] = fTmp[i];
  281.         break;
  282.             
  283.         case SS_ROTATI:
  284.         fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
  285.         if (nObjects <= 0)
  286.             GetRotMatrix(scene_rotMatrix, fTmp);
  287.         else
  288.             GetRotMatrix(obj_rotMatrix[nObjects-1], fTmp);
  289.         break;
  290.             
  291.         case  SS_SCALE:
  292.         fscanf(inf, "%f", fTmp);
  293.         if (nObjects > 0)
  294.             obj_scale[nObjects-1] = fTmp[0];
  295.         break;
  296.             
  297.         case SS_MATERI:
  298.         /* Build lit, shadow, and hilite material definition arrays */
  299.         if (nObjects <= 0) {
  300.             fprintf(stderr,
  301.             "Material definition does not follow an object.\n");
  302.             exit(1);
  303.         }
  304.         for (i=0; i<MATDEFLEN; i++) fHigh[i]=defaultHighMaterial[i];
  305.         for (i=0; i<MATDEFLEN; i++) fShad[i]=defaultShadowMaterial[i];
  306.         for (i=0; i<MATDEFLEN; i++)  fLit[i]=defaultLitMaterial[i];
  307.  
  308.         for (localDone = FALSE; !localDone; ) {
  309.             fscanf(inf, "%s", cmd);
  310.             switch (FindCommand(cmd)) {
  311.             case SS_SPECUL:
  312.             fscanf(inf, "%f %f %f", fLit+MATSPECOFF+1,
  313.                 fLit+MATSPECOFF+2, fLit+MATSPECOFF+3);
  314.             for (i=1; i<4; i++)
  315.                 fHigh[MATSPECOFF+i] = fLit[MATSPECOFF+i];
  316.             break;
  317.             case SS_SHININ:
  318.             fscanf(inf, "%f", fLit+MATSHINOFF+1);
  319.             fHigh[MATSHINOFF+1] = fLit[MATSHINOFF+1];
  320.             break;
  321.             case SS_DIFFUS:
  322.             fscanf(inf, "%f %f %f", fLit+MATDIFFOFF+1,
  323.                 fLit+MATDIFFOFF+2, fLit+MATDIFFOFF+3);
  324.             for (i=1; i<4; i++)
  325.                 fHigh[MATDIFFOFF+i] = fLit[MATDIFFOFF+i];
  326.             break;
  327.             case SS_EMISSI:
  328.             fscanf(inf, "%f %f %f", fLit+MATEMISOFF+1,
  329.                 fLit+MATEMISOFF+2, fLit+MATEMISOFF+3);
  330.             for (i=1; i<4; i++)
  331.                 fShad[MATEMISOFF+i] = fLit[MATEMISOFF+i];
  332.             break;
  333.             case SS_AMBIEN:
  334.             fscanf(inf, "%f %f %f", fLit+MATAMBIOFF+1,
  335.                 fLit+MATAMBIOFF+2, fLit+MATAMBIOFF+3);
  336.             for (i=1; i<4; i++)
  337.                 fShad[MATAMBIOFF+i] = fLit[MATAMBIOFF+i];
  338.             break;
  339.             case    SS_END:
  340.             lmdef(DEFMATERIAL,
  341.                 obj_litMaterial[nObjects-1] = iMaterial++,
  342.                 0, fLit);
  343.             lmdef(DEFMATERIAL,
  344.                 obj_shadowMaterial[nObjects-1] = iMaterial++,
  345.                 0, fShad);
  346.             lmdef(DEFMATERIAL,
  347.                 obj_highMaterial[nObjects-1] = iMaterial++,
  348.                 0, fHigh);
  349.             localDone = TRUE;
  350.             break;
  351.             default:
  352.             fprintf(stderr, "Unknown MATERIAL keyword: %s\n", cmd);
  353.             break;
  354.             }
  355.         }
  356.         break;
  357.  
  358.         case SS_TEXTUR:
  359.         /* Read and define a texture */
  360.         if (nObjects <= 0) {
  361.             fprintf(stderr,
  362.             "Texture definition does not follow an object.\n");
  363.             exit(1);
  364.         }
  365.         fscanf(inf,"%s", cmd);
  366.         ReadImg(cmd, &itex, &xtex, &ytex);
  367.         texdef2d(obj_texture[nObjects-1] = iTexture++, 4,
  368.             xtex, ytex, itex, 0, tex_val);
  369.         free(itex);
  370.         break;
  371.  
  372.         case  SS_LIGHT:
  373.         /* Build a light definition array */
  374.         iTmp = 0;
  375.         for (i=0; i<3; i++) {
  376.             light_posn[nLights][i] = defaultLight_posn[i];
  377.             jitter_light_range[nLights][i] = 0.0;
  378.         }
  379.         for (i=0; i<LGTDEFLEN; i++) fTmp[i] = defaultLight[i];
  380.  
  381.         for (localDone = FALSE; !localDone; ) {
  382.             fscanf(inf, "%s", cmd);
  383.             switch (FindCommand(cmd)) {
  384.             case SS_AMBIEN:
  385.             fscanf(inf, "%f %f %f", fTmp+LGTAMBOFF+1,
  386.                 fTmp+LGTAMBOFF+2, fTmp+LGTAMBOFF+3);
  387.             break;
  388.             case SS_LCOLOR:
  389.             fscanf(inf, "%f %f %f", fTmp+LGTCOLOFF+1,
  390.                 fTmp+LGTCOLOFF+2, fTmp+LGTCOLOFF+3);
  391.             break;
  392.             case SS_POSITI:
  393.             fscanf(inf, "%f %f %f %f", fTmp+LGTPOSOFF+1,
  394.                 fTmp+LGTPOSOFF+2, fTmp+LGTPOSOFF+3,
  395.                 fTmp+LGTPOSOFF+4);
  396.             x = fabs(fTmp[LGTPOSOFF+4]) < 0.01 ?
  397.                 0.01 : fTmp[LGTPOSOFF+4];
  398.             for (i=0; i<3; i++)
  399.                 light_posn[nLights][i] = fTmp[LGTPOSOFF+1+i]/x;
  400.             break;
  401.             case SS_SPOTDI:
  402.             fscanf(inf, "%f %f %f", fTmp+LGTSPDOFF+1,
  403.                 fTmp+LGTSPDOFF+2, fTmp+LGTSPDOFF+3);
  404.             break;
  405.             case SS_SPOTLI:
  406.             fscanf(inf, "%f %f %f", fTmp+LGTSPLOFF+1,
  407.                 fTmp+LGTSPLOFF+2, fTmp+LGTSPLOFF+3);
  408.             break;
  409.             case SS_JITTER:
  410.             fscanf(inf, "%f %f %f", jitter_light_range[nLights],
  411.                 jitter_light_range[nLights] + 1,
  412.                 jitter_light_range[nLights] + 2);
  413.             break;
  414.             case   SS_END:
  415.             lmdef(DEFLIGHT, nLights+1, 0, fTmp);
  416.             localDone = TRUE;
  417.             break;
  418.             default:
  419.             fprintf(stderr, "Unknown LIGHT keyword: %s\n", cmd);
  420.             break;
  421.             }
  422.         }
  423.         nLights++;
  424.         break;
  425.  
  426.         case    SS_END:
  427.         done = TRUE;
  428.         break;
  429.         default:
  430.         fprintf(stderr, "Unknown keyword: %s\n", cmd);
  431.         break;
  432.         }
  433.     }
  434.     }
  435.  
  436.  
  437.     /* Set defaults where unspecified */
  438.  
  439.     if (nObjects <= 0) {
  440.     /* If no objects defined, put three cubes in */
  441.     for (nObjects = 0; nObjects < 3; nObjects++) {
  442.         obj_drawlist[nObjects] = &glo_cube;
  443.         obj_data[nObjects] = GetPolyData(obj_drawlist[nObjects]);
  444.         vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
  445.         obj_litMaterial[nObjects] = -1;
  446.     }
  447.     vset(obj_posn[0],  1.35, -0.78, 0.0);
  448.     vset(fTmp, 20.0,  5.0, 17.0);
  449.     GetRotMatrix(obj_rotMatrix[0], fTmp);
  450.     obj_scale[0] = 1.0;
  451.  
  452.     vset(obj_posn[1], -1.35, -0.78, 0.0);
  453.     vset(fTmp, -5.0, 35.0, -35.0);
  454.     GetRotMatrix(obj_rotMatrix[1], fTmp);
  455.     obj_scale[1] = 1.2;
  456.  
  457.     vset(obj_posn[2],  0.00,  1.56, 0.0);
  458.     vset(fTmp, -19.0, 5.0, 5.0);
  459.     GetRotMatrix(obj_rotMatrix[2], fTmp);
  460.     obj_scale[2] = 1.4;
  461.     }
  462.  
  463.     /* Assign a gray material to any undefined objects */
  464.     lmdef(DEFMATERIAL, iMaterial, 0, FlatGray);
  465.     lmdef(DEFMATERIAL, iMaterial+1, 0, FlatGrayA);
  466.     lmdef(DEFMATERIAL, iMaterial+2, 0, FlatGrayH);
  467.     for (i=0; i<nObjects; i++)
  468.     if (obj_litMaterial[i] < 0) {
  469.         obj_litMaterial[i] = iMaterial;
  470.         obj_shadowMaterial[i] = iMaterial+1;
  471.         obj_highMaterial[i] = iMaterial+2;
  472.     }
  473.  
  474.     /* If no lights defined, put in a red one and a blue one */
  475.     if (nLights <= 0) {
  476.     lmdef(DEFLIGHT, 1, 0, RightRed);
  477.     lmdef(DEFLIGHT, 2, 0, LeftBlue);
  478.     nLights = 2;
  479.     vset(light_posn[0],  100.0,  100.0,  100.0);
  480.     vset(light_posn[1], -100.0,  100.0,  100.0);
  481.     vset(jitter_light_range[0], 10.0, 10.0, 10.0);
  482.     vset(jitter_light_range[1], 5.0, 5.0, 5.0);
  483.     }
  484.  
  485.     /* Define the light model */
  486.     lmdef(DEFLMODEL, 1, 0, theLModel);
  487.     lmbind(LMODEL, 1);
  488. }
  489.  
  490.  
  491. int
  492. FindCommand(char buf[]) {
  493.     int i;
  494.  
  495.     for (i=0; i<NSCENECMDS; i++)
  496.     if (strncmp(buf, SceneCommands[i].name,
  497.         strlen(SceneCommands[i].name)) == 0)
  498.         return SceneCommands[i].index;
  499.     return SS_UNDEFINED;
  500. }
  501.  
  502.  
  503. int
  504. GetRotMatrix(Matrix aMatrix, float r[]) {
  505.     /* Use GL hardware to get composite rotation matrix */
  506.     pushmatrix();
  507.     loadmatrix(IdentMat);
  508.     rot(r[0], 'x');
  509.     rot(r[1], 'y');
  510.     rot(r[2], 'z');
  511.     getmatrix(aMatrix);
  512.     popmatrix();
  513. }
  514.  
  515.  
  516. int
  517. ReadImg(char *filename, long **pbgImage, int *pbgXsize, int *pbgYsize) {
  518.     register IMAGE *image;
  519.     register int x, y, xsize, ysize;
  520.     register int z, zsize;
  521.     short buf[4096]; 
  522.  
  523.     if ((image=iopen(filename, "r")) == NULL ) {
  524.     fprintf(stderr,"readimg: can't open input file %s\n",filename);
  525.     return FALSE;
  526.     }
  527.     xsize = image->xsize;
  528.     ysize = image->ysize;
  529.     zsize = image->zsize;
  530.     if(zsize<3) {
  531.     fprintf(stderr,"readimg: this is not an RGB image file\n");
  532.     return FALSE;
  533.     }
  534.  
  535.     *pbgImage = (long *) malloc(xsize * ysize * sizeof(long));
  536.     *pbgXsize = xsize; *pbgYsize = ysize;
  537.  
  538.     for(y=0; y<ysize; y++) {
  539.     getrow(image,buf,y,0);    /* Red */
  540.     for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x]  = buf[x] | 0xff000000;
  541.     getrow(image,buf,y,1);    /* Green */
  542.     for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 8;
  543.     getrow(image,buf,y,2);    /* Blue */
  544.     for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 16;
  545.     }
  546.     return TRUE;
  547. }
  548.